#include "Common.h"
#include "Configure.h"
#include "App/AppBase.h"
#include "Utils/Util.h"
#include "Utils/Tokenizer.h"

using namespace RayFrame;

IMPL_SINGLETON(Configure);

#define CONFIGURE(name, defaultValue) char*     \
  RayFrame::Configure::varName_##name = (char*)#name;
#include "Configure.def"
#undef CONFIGURE

Configure::Configure()
{
  internalCreate();
}

Configure::~Configure(void)
{
  internalDestroy();
}

void Configure::internalCreate()
{
  LoadDefaultConfigure();

  m_filename = g_App->GetCmdArguments().empty() ?
    DEFAULT_CFG_NAME : g_App->GetCmdArguments();
  m_isOK = true;
}

void Configure::internalDestroy()
{
  if(!m_isOK)
    return;
}

void Configure::Create(STRING filename)
{
  if(!filename.empty() && FileExists(filename))
    m_filename = filename;
  
  if(!doLoadFromFile(m_filename))
  {
    m_isOK = false;
    throw new MyException("Error while loading configure file");
  }

  m_isOK = true;
}

void Configure::Destroy(bool save)
{
  if(save)
    SaveToFile(m_filename);
}

void Configure::LoadDefaultConfigure()
{
  #define CONFIGURE(name, defaultValue)   \
    m_cfgVarDefault[Trim(#name)] = STRING(Trim(#defaultValue)); \
    m_cfgVarNames[Cfg_##name] = #name;  \
    m_data[#name] = #defaultValue;
  #include "Configure.def"
  #undef CONFIGURE
}

bool Configure::doLoadFromFile(STRING filename)
{
  Tokenizer tok, lineTok;
  if(!tok.setFile(filename.c_str()))
    return false;

  char *crtToken;
  STRING key, value;
  while((crtToken = tok.next()) != NULL)
  {
    key = Trim(crtToken);
    if(key.empty())
      continue;

    if( strcmp(tok.next(), "=") != 0 )
    {
      assert(false);
    }
    value = Trim(tok.nextLine());

    m_data[key] = value;
  }

  return true;
}

bool Configure::SaveToFile(STRING filename)
{
  FILE* outFile = fopen(filename.c_str(), "w");
  if(!outFile)
    return false;

  IterStrSTr iter = m_data.begin();
  while(iter != m_data.end())
  {
    STRING key, value;
    key = Trim(iter->first.c_str());
    value = Trim(iter->second.c_str());
    fprintf(outFile, "%s = %s\n", key.c_str(), value.c_str());
    iter++;
  }

  fclose(outFile);
  return true;
}
